﻿namespace UFIDA.U9.Cust.STR.SyncSV
{
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Net;
    using System.Reflection.Emit;
    using System.Text;
    using UFIDA.U9.Base.Contact;
    using UFIDA.U9.Base.Organization;
    using UFIDA.U9.CBO.HR.CBOHRSV;
    using UFIDA.U9.CBO.HR.CBOHRSV.Proxy;
    using UFIDA.U9.CBO.HR.Department;
    using UFIDA.U9.CBO.HR.Operator;
    using UFIDA.U9.CBO.HR.Person;
    using UFIDA.U9.CBO.HR.Position;
    using UFIDA.U9.Cust.STR.SyncSV.Dtos;
    using UFIDA.U9.Cust.STR.SyncSV.Public;
    using UFSoft.UBF.AopFrame;
    using UFSoft.UBF.Business;
    using UFSoft.UBF.Util.Context;
    using UFSoft.UBF.Util.DataAccess;

    /// <summary>
    /// OAOperatorSyncService partial 
    /// </summary>	
	public partial class OAOperatorSyncService
    {
        internal BaseStrategy Select()
        {
            return new OAOperatorSyncServiceImpementStrategy();
        }
    }

    #region  implement strategy	
    /// <summary>
    /// Impement Implement
    /// 
    /// </summary>	
	internal partial class OAOperatorSyncServiceImpementStrategy : BaseStrategy
    {
        public OAOperatorSyncServiceImpementStrategy() { }

        public override object Do(object obj)
        {
            OAOperatorSyncService bpObj = (OAOperatorSyncService)obj;

            DataAccessor.RunSQL(DataAccessor.GetConn(), $@"select top 1 SyncDate from Cust_OAOperator order by SyncDate desc", null, out DataSet countDS);
            string modifiedDate;
            if (countDS.Tables[0].Rows.Count == 0)
            {
                modifiedDate = $"{new DateTime(1970, 1, 1):yyyy-MM-dd HH:mm:ss}";
            }
            else
            {
                modifiedDate = $"{countDS.Tables[0].Rows[0][0]:yyyy-MM-dd HH:mm:ss}";
            }
            HttpHelper httpHelper = new HttpHelper();
            JsonConfig _config = new JsonConfig();
            var OAUrl = _config.SelectToken("OA.URL");
            httpHelper.URL = OAUrl + "/api/hrm/resful/getHrmUserInfoWithPage";
            var postPara = new
            {
                @params = new
                {
                    modified = modifiedDate,
                    pagesize = 999,
                    curpage = 1
                }
            };
            httpHelper.Content = JsonConvert.SerializeObject(postPara);
            httpHelper.OAGetToken();
            var postResult = httpHelper.Request();
            JObject jObject = JObject.Parse(postResult);
            JArray dataList = (JArray)jObject["data"]["dataList"];
            if (dataList.Count == 0)
                return null;
            StringBuilder sql = new StringBuilder(@"INSERT INTO Cust_OAOperator ( [created]
           ,[departmentcode]
           ,[modified]
           ,[id]
           ,[certificatenum]
           ,[mobile]
           ,[sex]
           ,[lastname]
           ,[workcode]
           ,[subcompanycode]
           ,[UseFlag]
           ,[SyncDate]) VALUES ");
            List<OAOperator> opers = new List<OAOperator>();
            foreach (JObject item in dataList)
            {
                OAOperator oper = new OAOperator();
                oper.departmentCode = item["departmentcode"].ToString();
                oper.created = Convert.ToDateTime(item["created"]);
                oper.modified = Convert.ToDateTime(item["modified"]);
                oper.id = Convert.ToInt32(item["id"]);
                oper.certificateNum = item["certificatenum"].ToString();
                oper.mobile = item["mobile"].ToString();
                oper.sex = item["sex"].ToString();
                oper.lastname = item["lastname"].ToString();
                oper.workcode = item["workcode"].ToString();
                oper.subcompanycode = item["subcompanycode"].ToString();
                oper.birthday = PublicMethod.GetBirthday(item["birthday"].ToString(), item["certificatenum"].ToString());
                DateTime companystartdate;
                if (!string.IsNullOrEmpty(item["companystartdate"].ToString().Trim()))
                {
                    DateTime.TryParse(item["companystartdate"].ToString(), out companystartdate);
                }
                else
                {
                    companystartdate = Convert.ToDateTime(item["created"]).Date;
                }
                oper.companystartdate = companystartdate;
                oper.UseFlag = false;
                oper.SyncDate = DateTime.Now;
                opers.Add(oper);

                sql.Append($"('{oper.created}','{oper.departmentCode}','{oper.modified}','{oper.id}','{oper.certificateNum}','{oper.mobile}','{oper.sex}','{oper.lastname}','{oper.workcode}','{oper.subcompanycode}',0,getdate()),");
            }

            // Remove the last comma and add a semicolon
            sql.Length--;
            sql.Append(";");
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql.ToString(), null);

            List<OAOperator> succList = new List<OAOperator>();
            var operIDCodes = opers.Where(t => !string.IsNullOrEmpty(t.certificateNum)).Select(t => t.certificateNum).ToList();
            if (operIDCodes.Count > 0)
            {
                //var exsitOpers = Operators.Finder.FindAll($"Code in ({string.Join(",", operCodes.Select(t => $"'{t}'"))})").Cast<Operators>().ToList();
                //var exsitOpers = Person.Finder.FindAll($"PersonID in ({string.Join(",", operIDCodes.Select(t => $"'{t}'"))})").Cast<Person>().ToList();
                List<Organization> orgs = Organization.Finder.FindAll("IsOperatingOrg = 1").Cast<Organization>().ToList();
                //List<Department> depts = Department.Finder.FindAll($"Code in ({string.Join(",", opers.Select(t => $"'{t.departmentCode}'").Distinct())})").Cast<Department>().ToList();
                List<Department> depts = PublicMethod.GetDistinctElements<Department>("Code", opers.Select(t => t.departmentCode));
                opers = opers.Where(t => !string.IsNullOrEmpty(t.workcode) && !string.IsNullOrEmpty(t.certificateNum)).ToList();
                var national = Base.Location.Country.FindByCode("142");
                var personcategory = CBO.HR.EmploymentCategory.EmployCategory.Finder.FindAll("Code = 'C003'").Cast<CBO.HR.EmploymentCategory.EmployCategory>().ToList();
                var Contacts = Contact.Finder.FindAll("").Cast<Contact>().ToList();
                var Positions = PublicMethod.GetDistinctElements<Position>("Department.Code", opers.Select(t => t.departmentCode));
                //var exsitOpers = EntityArrayFinder<EmployeeArchive>.GetDistinctElements("EmployeeCode", opers.Select(t => t.workcode)).Select(t => t.Person).ToList();
                var exsitOpers = PublicMethod.GetDistinctElements<Person>("PersonID", opers.Select(t => t.certificateNum));
                //using (UFSoft.UBF.Business.ISession session = Session.Open())
                //{
                foreach (var operGroup in opers.GroupBy(t => t.subcompanycode))
                {
                    PersonADDSVProxy addsv = new PersonADDSVProxy();
                    PersonModifySVProxy modifysv = new PersonModifySVProxy();
                    var org = orgs.FirstOrDefault(t => t.Code == operGroup.Key);
                    if (org == null)
                    {
                        continue;
                    }
                    addsv.TargetOrgCode = operGroup.Key;
                    addsv.PersonDTOs = new List<PersonDTOData>();
                    modifysv.TargetOrgCode = operGroup.Key;
                    modifysv.PersonDTOs = new List<PersonDTOData>();
                    foreach (var oper in operGroup)
                    {
                        PersonDTOData dto = new PersonDTOData();
                        var dept = depts.FirstOrDefault(t => t.Code == oper.departmentCode && t.Org.Code == org?.Code) ?? depts.FirstOrDefault(t => t.Org.Code == org?.Code);
                        if (dept != null)
                        {
                            var postion = Positions.LastOrDefault(t => t.Department.Code == dept?.Code) ?? Position.Finder.Find($"Name like '%ERP%' and Org = {org.ID}") ?? Position.Finder.Find($"Org = {org.ID} order by Code desc");
                            if (postion == null)
                                continue;
                            bool isAdd = false;
                            if (exsitOpers.FirstOrDefault(t => t.PersonID == oper.certificateNum) == null)
                            {
                                isAdd = true;
                            }
                            var op = exsitOpers.FirstOrDefault(t => t.PersonID == oper.certificateNum) ?? Person.Create();
                            if (op.AttachOrg != null && op.AttachOrg.Code != org.Code)
                                continue;
                            //op.Name = oper.lastname;

                            //contact = contact ?? Contact.Create();
                            //if (!string.IsNullOrEmpty(oper.mobile))
                            //{
                            //    var mobils = contact.Mobils.Count == 0 ? contact.Mobils.AddNew() : contact.Mobils[0];
                            //    mobils.MobilNum = oper.mobile;
                            //    mobils.Usage = ContactUsageEnum.Personal;
                            //}
                            //op.Sex = GenderEnum.GetFromValue(oper.sex == "男" ? 0 : 1);
                            //op.Birthday = oper.birthday;
                            dto.Sex = oper.sex == "男" ? "0" : "1";
                            //adddto.Birthday
                            dto.StartDate = oper.companystartdate.AddDays(-1);
                            dto.Country = national.Code;
                            dto.CertificateType = oper.certificateNum;
                            dto.AssgnBeginDate = oper.companystartdate;
                            dto.BusinessOrgCode = org.Code;
                            dto.CreateOrgCode = org.Code;
                            dto.DeptCode = dept.Code;
                            dto.EmployeeCategoryCode = "C003";
                            dto.LastName = oper.lastname.Substring(0,1);
                            dto.FirstName = oper.lastname.Substring(1, oper.lastname.Length - 1);
                            dto.HROrgCode = org.Code;
                            //dto.JobCode = oper.workcode;
                            dto.OwnerOrgCode = org.Code;
                            dto.PersonCode = oper.workcode;
                            dto.PositionCode = postion.Code;
                            dto.SuperiorPositionCode = postion.Code;
                            dto.SuperiorWorkOrgCode = org.Code;
                            dto.WorkingOrgCode = org.Code;
                            if (isAdd)
                                addsv.PersonDTOs.Add(dto);
                            else
                                modifysv.PersonDTOs.Add(dto);
                            //op.OccupationDate = oper.companystartdate;
                            //op.Nationality = national;
                            //op.CertificateType = CBO.HR.Enums.CertificateTypeEnum.PIDCard;
                            //var contact = Contacts.FirstOrDefault(t => t.DefaultMobilNum == oper.mobile) ?? Contacts.FirstOrDefault(t => t.Code == oper.certificateNum);
                            //if (contact == null)
                            //{
                            //    contact = Contact.Create();
                            //    contact.IsEmployeeContact = true;
                            //    contact.Code = oper.certificateNum;
                            //    contact.Gender = GenderEnum.GetFromValue(oper.sex == "男" ? 0 : 1);
                            //    contact.Name = op.Name;
                            //    contact.DefaultMobilNum = oper.mobile;
                            //    contact.ContactType = ContactTypeEnum.Person;
                            //}
                            //op.LinkMan = contact;
                            //op.PersonID = oper.certificateNum;
                            //op.MobilePhone = oper.mobile;
                            //op.LastName = oper.lastname.Substring(1);
                            //op.FirstName = oper.lastname.Substring(1, oper.lastname.Length - 1);
                            //if (op.EmployeeArchives.Count == 0)
                            //{
                            //    var arch = op.EmployeeArchives.AddNew();
                            //    arch.OwnerOrg = org;
                            //    arch.WorkingOrg = org;
                            //    arch.EntranceDate = oper.companystartdate;
                            //    arch.EmployeeCode = oper.workcode;
                            //    if (arch.EntranceDate < op.OccupationDate)
                            //        arch.EntranceDate = op.OccupationDate;
                            //    arch.BusinessOrg = org;
                            //    arch.Dept = dept;
                            //    if (arch.Position == null)
                            //        arch.Position = postion;

                            //    if (arch.PersonCategory == null)
                            //        arch.PersonCategory = personcategory.FirstOrDefault(t => t.Org.Code == org.Code);
                            //}
                            //if (op.EmployeeAssignments.Count == 0)
                            //{
                            //    var assig = op.EmployeeAssignments.AddNew();
                            //    if (assig.Position == null)
                            //        assig.Position = postion;
                            //    assig.OwnerOrg = org;
                            //    assig.BusinessOrg = org;
                            //    assig.WorkOrg = org;
                            //    assig.AssgnBeginDate = oper.companystartdate;
                            //    if (assig.AssgnBeginDate < op.OccupationDate)
                            //        assig.AssgnBeginDate = op.OccupationDate;
                            //    assig.Dept = dept;
                            //    assig.IsMain = true;

                            //    if (isAdd)
                            //    {
                            //        assig.PositionStatus = CBO.HR.Enums.EmPositonStatusEnum.OnPosition;
                            //    }
                            //}

                            //succList.Add(oper);
                        }
                    }
                    StringBuilder sb = new StringBuilder();
                    if (addsv.PersonDTOs.Count > 0)
                        sb.AppendLine(addsv.Do());
                    if (modifysv.PersonDTOs.Count > 0)
                        sb.AppendLine(modifysv.Do());
                    LogManager.WriteLog(sb.ToString(),"PersonSV");
                }
                //    session.Commit();
                //}
            }
            if (succList.Count > 0)
            {
                string upSql = $@"update Cust_OAOperator set UseFlag = 1 where id in ({string.Join(",", succList.Select(t => t.id))}) and SyncDate >= DATEADD(MINUTE,-3,GETDATE())";
                DataAccessor.RunSQL(DataAccessor.GetConn(), upSql, null);
            }
            return "";
        }
    }

    #endregion


}